package com.franklin.java.action.sql;

import com.franklin.java.api.action.AbstractAction;
import com.franklin.java.api.mybatis.dom.utils.MapperUtils;
import com.franklin.java.completion.map.MapData;
import com.franklin.java.completion.map.mybatis.MapperMethodHandler;
import com.franklin.java.entity.sql.ColumnInfo;
import com.franklin.java.utils.ProjectUtils;
import com.franklin.plugins.common.utils.DataCheckUtils;
import com.intellij.find.FindManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.NlsActions;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.xml.XmlTag;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import javax.swing.*;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author Franklin
 * @since 2021/9/7 11:07
 */
public abstract class AbstractSqlAction extends AbstractAction<PsiElement> {

    protected final PsiElement sqlActionElement;

    protected Project project;

    public AbstractSqlAction(@Nullable @NlsActions.ActionText String text, @Nullable @NlsActions.ActionDescription String description, @Nullable Icon icon, PsiElement sqlActionElement) {
        super(text, description, icon);
        this.sqlActionElement = sqlActionElement;
        this.project = sqlActionElement.getProject();
    }

    public PsiMethod getMapperMethod(){
        String target = null;
        String mapperClass = null;
        PsiMethod mapperMethod = null;
        if (sqlActionElement instanceof XmlTag){
            XmlTag xmlTag = (XmlTag) sqlActionElement;
            target = xmlTag.getAttributeValue("id");
            XmlTag mapperTag = xmlTag.getParentTag();
            if (Objects.nonNull(mapperTag)) {
                mapperClass = mapperTag.getAttributeValue("namespace");
                String path = sqlActionElement.getContainingFile().getVirtualFile().getPath();
                mapperMethod = MapperUtils.findMapperMethod(project,path,mapperClass,target);
            }
        }else if (sqlActionElement instanceof PsiMethod){
            mapperMethod = (PsiMethod) sqlActionElement;
        }
        return mapperMethod;
    }

    protected void startFindUsages(@NotNull PsiElement element) {
        FindManager.getInstance(element.getProject()).findUsages(element);
    }

    protected Map<String, MapData> resolveSql() {
        MapperMethodHandler mapperMethodHandler = new MapperMethodHandler(project);
        List<MapData> columnInfos = mapperMethodHandler.resolveMethod(getMapperMethod());
        Map<String, MapData> cache = columnInfos.stream()
            .collect(Collectors.toMap(mapData -> mapData.getKey().getValue(), Function.identity()));
        return DataCheckUtils.isEmpty(cache) ? Collections.emptyMap() : cache;
    }

    protected List<ColumnInfo> resolveSql2Columns(){
        MapperMethodHandler mapperMethodHandler = new MapperMethodHandler(project);
        return mapperMethodHandler.resolveColumnInfo(getMapperMethod());
    }
}
